#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <wait.h>
#include "sem.c"
#include "shm.c"

#define N_NIM	5

void nim( int i ) ;
void barreira();

int nfilhos;
int *count;
int exmut;
int block;

int main(int argc, char **argv)
{
	int i, mem;

	if( argc != 2 )
	{	printf( "uso %s num_filhos\n", argv[0] );
		exit(1);
	}

	nfilhos = atoi(argv[1]);

	//cria uma zona de memória partilhada
	mem = createSharedArea(sizeof(int));
	count = attachArea(mem);

	//cria os semáforos usados na barreira
	exmut = createSem(1);
	block = createSem(0);
	*count = 0;

	for( i = 0; i < nfilhos; i++ )
		if( fork() == 0 )
		{	
			nim(i);
			exit(0);
		}

	for( i = 0; i < nfilhos; i++ )
		wait(NULL);

	printf( "fim!\n" );

	//apagar semaforos e segmento de memória
	deleteSharedArea(mem);
	deleteSem(exmut);
	deleteSem(block);
	return 0;
}

void barreira()
{
	int i;
	//decrementa o semáforo, para haver apenas um processo em execução
	P(exmut); 
	//incrementa o número de processos bloqueados, ou seja, que já imprimiram a sua mensagem
	*count = *(count) + 1;

	if (*count<nfilhos)
	{
		V(exmut); 
		P(block); 
		P(exmut);
	}
	else
	{
		//se for o ultimo processo, então acorda todos os processos, para se passar à escrita da próxima mensagem
		for (i = 1; i<nfilhos; i++)
			V(block);
		*count = 0;
	}
 	V(exmut);
}

void nim(int i)
{
	int pid = getpid();
	int n, j;

	for( n = 1; n <= N_NIM; n++ )
	{
		printf("Filho %d - <%d> Mensagem %d\n", i, pid, n );
		barreira();
	}
}



